/*
 * Menu.h
 *
 *  Created on: Dec 12, 2011
 *      Author: Michael Anderson
 *      Part of Team 955 Battery Cart project
 *      compiled on Eclipse with Arduino libraries and avr-gcc
 */

#ifndef MENU_H_
#define MENU_H_

#include "Display.h"
#include "MyKeypad.h"
#include "EventManager.h"
#include "Battery.h"
#include "Charger.h"
#include "Conditioner.h"
#include "EventCallback.h"
#include "Utils.h"
#include "enums.h"
#include "Timer.h"
#include <stdio.h>
#include <string.h>
#include <HardwareSerial.h>
#include <MemoryFree.h>

#define MENU_HOME_ENTRIES 3
#define KEY_MENU_BACK '*'
#define KEY_MENU_CONFIRM '#'
#define KEY_OPEN_QUEUE '0'
#define KEY_OPEN_WATT_MENU '0'
#define KEY_START_CHARGE '1'
#define KEY_START_COND '2'
#define KEY_START_QUICK_TEST '3'
#define KEY_START_HIGH_RATE_TEST '4'
#define KEY_SUBMENU_FORWARDS '9'
#define KEY_SUBMENU_BACK '7'

class Menu : EventCallback {
public:
    Menu(Display*(&)[NUM_DISPLAYS], MyKeypad&, EventManager&, Battery*(&)[NUM_CHARGING_CIRCUITS], Charger*(&)[NUM_CHARGING_CIRCUITS], Conditioner*(&)[NUM_CHARGING_CIRCUITS / 2]);
    void run();
    void _chargerEventCallback(uint8_t, charger_event);
    void _conditionerEventCallback(uint8_t, uint8_t, conditioner_event);

private:
    MyKeypad *keypd;
    Display **displays;
    EventManager *eManager;
    Battery **batteries;
    Conditioner **conditioners;
    Charger **chargers;
    uint8_t curBattID;
    bool inSubMenu;
    menu_state state;
    menu_state lastState;
    menu_action promptAction;
    uint32_t wattHourUpdateTimer;
    queue_action actionQueue[NUM_CHARGING_CIRCUITS][QUEUE_MAX_DEPTH];
    uint8_t actionQueueStart[NUM_CHARGING_CIRCUITS];
    double wattHourReadings[NUM_CHARGING_CIRCUITS];
    uint8_t resultsMenuPage;
    uint8_t debugMenuPage;
    uint32_t debugMenuRefreshTimer;
    uint32_t loopStartTime;
    uint16_t lastLoopTime;
    battery_quick_test_status quickTestResults[NUM_CHARGING_CIRCUITS];
    double highRateTestResults[NUM_CHARGING_CIRCUITS];

    void updateStatus();
    void showHomeMenu();
    void showBatteryMenu(uint8_t battID);
    void showPromptMenu(char*[], uint8_t);
    void showQueueMenu(uint8_t battID);
    void showResultsMenu(uint8_t page);
    void showDebugMenu(uint8_t);
    void showConditionTypeMenu();
    void refreshMenu();
    bool connectCharger(uint8_t);
    bool connectConditioner(uint8_t battID, discharge_type type, bool waitForTest = false);
    bool disconnectCharger(uint8_t);
    bool disconnectConditioner(uint8_t);
    uint8_t getCharInt(char);
    queue_action popQueue(uint8_t);
    queue_action queueGetNext(uint8_t);
    bool queueIsEmpty(uint8_t);
    void advanceQueue(uint8_t);
    void clearQueue(uint8_t);
    bool queueAction(uint8_t, queue_action);
    bool chargeIsInQueue(uint8_t);
    void clearResults();
};

#endif /* MENU_H_ */
